/*
 * Multi Selectify 0.1 - jQuery Plugin
 * 
 * Copyright (c) 2009 Tom Usher - http://www.tomusher.co.uk
 * 
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 */

(function($) {
$.fn.multiSelectify = function(options) {
	var opts = $.extend({}, $.fn.multiSelectify.defaults, options);
	var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
		
	this.each(function(i) {
		if(opts.hideSelect) $(this).hide();
		
		while($("#"+opts.componentClass + i).size() > 0) i++; 
		
		var multiSelect = $(this);		//Original select element
		var sourceList = $("<ul>");		//List of unselected items
		var destList = $("<ul>");		//List of selected items
		var sourceContainer = $("<div>");	//Container for list of unselected items
		var destContainer = $("<div>");		//Container for list of selected items
		var multiItem = $("<div>");			//Wrapper for new component
		
		$(multiItem)
			.addClass(opts.componentClass)
			.attr("id",opts.componentClass+i);
		$(sourceContainer)
			.addClass(opts.containerClass)
			.addClass(opts.sourceContainerClass);
		$(destContainer)
			.addClass(opts.containerClass)
			.addClass(opts.destContainerClass);
		
		$(multiItem).append(sourceContainer);
		$(multiItem).append(destContainer);
		
		$("option", multiSelect).each(function(n) {
			var listItem = $("<li>");
			$(listItem).append($(this).text());
			listItem.val($(this).val());
			listItem.data("relatedId",n);
			$(this).data("relatedId",n);
			if($(this).is(":selected")) {
				$(listItem).appendTo(destList);
			} else {
				$(listItem).appendTo(sourceList);
			}
		});
		
		$(sourceContainer).append(jQuery("<h3>").append(opts.sourceTitle));
		$(destContainer).append(jQuery("<h3>").append(opts.destTitle));

		$(sourceContainer).append(sourceList);
		$(destContainer).append(destList);
	
		$(multiItem).insertAfter(this);
		
		$("#"+opts.componentClass+i+" ul").sortable({
			connectWith: "#"+opts.componentClass+i+' ul',
			placeholder: 'multi-list-highlight',
			update: function(event, ui) {
				updateMultiSelect(ui.item);
				
			}
		}).disableSelection();
		
		$("li", "#"+opts.componentClass+i).dblclick(function() {
			var parent = $(this).parent().parent();
			if($(parent).hasClass(opts.sourceContainerClass)) {
				$(this).appendTo($("."+opts.destContainerClass+" ul", "#"+opts.componentClass+i));
			} else {
				$(this).appendTo($("."+opts.sourceContainerClass+" ul", "#"+opts.componentClass+i));
			}
			updateMultiSelect($(this));
		});
		
		function updateMultiSelect(el) {
			if($(el).parent().parent().hasClass(opts.destContainerClass)) {
				$("[relatedId="+$(el).data("relatedId")+"]", multiSelect).attr("selected","selected");
			} else {
				$("[relatedId="+$(el).data("relatedId")+"]", multiSelect).removeAttr("selected");
			}
			var optionToUpdate = $("option[relatedId="+$(el).data("relatedId")+"]",multiSelect);
			var prevOption = $("option[relatedId="+$(el).prev().data("relatedId")+"]",multiSelect);
			if(prevOption.length) {
				$(prevOption).after(optionToUpdate);
			} else {
				$(multiSelect).prepend(optionToUpdate);
			}
		};


	});
	return this;
};

$.fn.multiSelectify.defaults = {
	sourceTitle: 'Deselected',
	destTitle: 'Selected',
	containerClass: 'multi-list',
	componentClass: 'multi-list-area',
	sourceContainerClass: 'multi-list-source',
	destContainerClass: 'multi-list-dest',
	hideSelect: true
};
})(jQuery);

// James Padolsey's 'Better Data Selector' 
// http://james.padolsey.com/javascript/a-better-data-selector-for-jquery/
(function($){
    var _dataFn = $.fn.data;
    $.fn.data = function(key, val){
        if (typeof val !== 'undefined'){ 
            $.expr.attrHandle[key] = function(elem){
                return $(elem).attr(key) || $(elem).data(key);
            };
        }
        return _dataFn.apply(this, arguments);
    };
})(jQuery);